package me.zhengjie.common.utils.byteUtils

import kotlin.math.pow

/**
 *
 * Author:Think
 *
 * Time:2021/2/3 10:14
 *
 * Description:This is DataTransfor
 *
 */
object DataTransform {
    //https://www.iteye.com/blog/aub-1129228
    //https://github.com/FirebirdSQL/decimal-java
    /**
     *
     * 用于建立十六进制字符的输出的小写字符数组
     *
     */
    private val DIGITS_LOWER = charArrayOf(
        '0', '1', '2', '3', '4', '5',
        '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
    )

    /**
     *
     * 用于建立十六进制字符的输出的大写字符数组
     *
     */
    private val DIGITS_UPPER = charArrayOf(
        '0', '1', '2', '3', '4', '5',
        '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
    )

    /**
     *
     * @Desc: 字节转十六进制字符串
     *
     * @Author: Aries.hu
     *
     * @Date: 2021/2/3 11:19
     */
    fun byteToHex(b: Byte): String {
        var hex = Integer.toHexString(b.toInt() and 0xFF)
        if (hex.length < 2) {
            hex = "0$hex"
        }
        return hex
    }

    /**
     *
     * @Desc: 字节数组转字符串
     *
     * @Author: Aries.hu
     *
     * @Date: 2021/2/3 11:19
     */
    fun bytesToHex(bytes: ByteArray): String {
        val sbuffer = StringBuilder()
        for (aByte in bytes) {
            val hex = Integer.toHexString(aByte.toInt() and 0xFF)
            if (hex.length < 2) {
                sbuffer.append(0)
            }
            sbuffer.append(hex)
        }
        return sbuffer.toString()
    }

    /**
     *
     * @Desc: 数组倒序
     *
     * @Author: Aries.hu
     *
     * @Date: 2021/2/3 15:15
     */
    fun bytesArrayReverse(src: ByteArray?): ByteArray? {
        var temp: Byte = 0
        val len = src!!.size
        for (i in 0 until len / 2) {
            temp = src[i]
            src[i] = src[len - i - 1]
            src[len - i - 1] = temp
        }
        return src
    }

    /**
     *
     * @Desc: byte数组转换为二进制字符串,每个字节以","隔开
     *
     * @Author: Aries.hu
     *
     * @Date: 2021/2/3 15:47
     */
    fun byteArrToBinStr(b: ByteArray): String {
        val result = StringBuffer()
        for (i in b.indices) {
            result.append(java.lang.Long.toString((b[i].toInt() and 0xff).toLong(), 2) + ",")
        }
        return result.toString().substring(0, result.length - 1)
    }

    /**
     *
     * @Desc: 二进制字符串转换为byte数组,8位一个字节
     *
     * @Author: Aries.hu
     *
     * @Date: 2021/2/3 15:48
     */
    fun binStrToByteArr(binStr: String): ByteArray {
        var binStr = binStr
        if ("" == binStr) {
            return ByteArray(0)
        }
        val bits = 8
        var str_len = 0
        var byte_len = 0
        val binStrBuilder = StringBuilder(binStr)
        while (binStrBuilder.length < 32) {
            binStrBuilder.append("0")
        }
        binStr = binStrBuilder.toString()
        str_len = binStr.length
        println(binStr)
        if (str_len % bits == 0) {
            byte_len = str_len / bits
        }
        val b = ByteArray(byte_len)
        var index = 0
        for (i in 0 until binStr.length) {
            val s = binStr.substring(i, i + bits)
            println(s)
            b[index] = bit2byte(s)
            index++
        }
        return b
    }

    internal fun encodeHexStr(data: ByteArray?, toDigits: CharArray): String {
        return String(encodeHex(data, toDigits))
    }

    /**
     *
     * @Desc: 字节数组转十六进制字符串
     *
     * @Author: Aries.hu
     *
     * @Date: 2021/2/5 11:48
     */
    fun encodeHexStr(data: ByteArray?, toLowerCase: Boolean): String {
        return encodeHexStr(data, if (toLowerCase) DIGITS_LOWER else DIGITS_UPPER)
    }

    /**
     *
     * @Desc: 将字节数组转换为十六进制字符数组
     *
     * @Author: Aries.hu
     *
     * @Date: 2021/2/5 11:47
     */
    internal fun encodeHex(data: ByteArray?, toDigits: CharArray): CharArray {
        val l = data!!.size
        val out = CharArray(l shl 1)

// two characters form the hex value.
        var i = 0
        var j = 0
        while (i < l) {
            out[j++] = toDigits[0xF0 and data[i].toInt() ushr 4]
            out[j++] = toDigits[0x0F and data[i].toInt()]
            i++
        }
        return out
    }

    fun bit2byte(bString: String): Byte {
        return bString.reversed().fold(0.toByte()) { acc, char ->
            (acc.toInt() + (char.digitToInt() * 2.0.pow(bString.length - 1 - bString.indexOf(char))).toInt()).toByte()
        }
    }

    /**
     *
     * @Desc: 字节数组转二进制字符串
     *
     * @Author: Aries.hu
     *
     * @Date: 2021/2/3 10:24
     */
    fun bytes2BinaryStr(bytes: ByteArray): String {
        val binaryStr = StringBuilder()
        for (aByte in bytes) {
            val str = Integer.toBinaryString((aByte.toInt() and 0xFF) + 0x100).substring(1)
            binaryStr.append(str)
        }
        return binaryStr.toString()
    }

    /**
     *
     * @Desc: int转byte数组
     *
     * @Author: Aries.hu
     *
     * @Date: 2021/2/5 21:21
     */
    fun intToByteArray(i: Int): ByteArray {
        val result = ByteArray(4)

// 由高位到低位
        result[0] = (i shr 24 and 0xFF).toByte()
        result[1] = (i shr 16 and 0xFF).toByte()
        result[2] = (i shr 8 and 0xFF).toByte()
        result[3] = (i and 0xFF).toByte()
        return result
    }
}